package com.base.cn.platform.os.service.course.cou.packageCou;

import com.base.cn.platform.os.common.mybatis.BaseBiz;
import com.base.cn.platform.os.common.utils.DataUtil;
import com.base.cn.platform.os.common.utils.ObjectUtils;
import com.base.cn.platform.os.common.utils.StringUtils;
import com.base.cn.platform.os.dao.course.cou.packageCou.PackageCourseDao;
import com.base.cn.platform.os.entity.course.cou.Course;
import com.base.cn.platform.os.entity.course.cou.buy.CourseBuyPackageCourse;
import com.base.cn.platform.os.entity.course.cou.buy.CourseBuyRecord;
import com.base.cn.platform.os.entity.course.cou.packageCou.PackageCourse;
import com.base.cn.platform.os.service.course.cou.CourseBiz;
import com.base.cn.platform.os.service.course.cou.buy.CourseBuyPackageCourseBiz;
import com.base.cn.platform.os.service.course.cou.buy.CourseBuyRecordBiz;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 套餐与课程关联的Biz
 *
 * @author s.li
 * @create 2018-05-02-14:51
 */
@Service
public class PackageCourseBiz extends BaseBiz<PackageCourse,PackageCourseDao> {

    @Autowired
    private CourseBiz courseBiz;
    @Autowired
    private CourseBuyRecordBiz courseBuyRecordBiz;
    @Autowired
    private CourseBuyPackageCourseBiz courseBuyPackageCourseBiz;
    @Autowired
    private PackageCourseDao packageCourseDao;

    /**
     * 创建阶段
     * @param packageId 套餐ID
     * @param stageContext 阶段内容
     */
    public void createStage(BigDecimal packageId,String stageContext){
        PackageCourse packageCourse = new PackageCourse();
        packageCourse.setPackageId(packageId);//设置套餐ID
        packageCourse.setStageContext(stageContext);
        packageCourse.setPackageType(2);//阶段类型
        packageCourse.setRequired(2);//阶段是非必须
        this.save(packageCourse);
    }

    /**
     * 保存套餐与课程的关联
     * @param packageCourseList 保存的数据列表
     */
    @Transactional
    public void savePackageCourse(List<PackageCourse> packageCourseList,Course course,BigDecimal packageId){
        this.batchSave(packageCourseList);
        //计算套餐套餐拥有课程时长,进行套餐更新
        Integer sum = packageCourseDao.getCourseDurationSum(course.getId());
        if(sum == null){
            sum = 0;
        }
        Course saveCourse = new Course();
        saveCourse.setId(course.getId());
        saveCourse.setTotleTimes(sum);
        courseBiz.updateById(saveCourse,null);
        this.setCourseService(packageCourseList,course,1,packageId);
    }

    /**
     * 删除套餐与课程的关联数据
     * @param ids 记录ID串
     */
    @Transactional
    public void deletePackageCourse(String ids,Course course,BigDecimal packageId){
        this.deleteWhereSql(" id in ("+ids+") or parentId in ("+ids+")");
        //获取课程其余的关联课程
        List<PackageCourse> packageCourses = this.find(" packageId = "+packageId, null, null);
        this.setCourseService(packageCourses,course,2,packageId);
    }

    /**
     * 修改套餐与课程关联的价格
     * @param id 记录ID
     * @param price 新的价格
     */
    public void updatePackageCoursePrice(BigDecimal id,Double price){
        PackageCourse packageCourse = new PackageCourse() ;
        packageCourse.setPrice(price);
        this.updateByWhereSql(packageCourse," id =" +id);
    }

    /**
     * 修改套餐与课程关联的排序
     * @param id
     * @param sort
     * @return
     */
    public void updatePackageCourseSort(BigDecimal id,Integer sort){
        PackageCourse packageCourse = new PackageCourse() ;
        packageCourse.setSort(sort);
        this.updateByWhereSql(packageCourse," id =" +id);
    }

    /**
     * 修改套餐与课程关联的必须状态
     * @param id 记录ID
     * @param required 1.必选 2.非必选
     */
    public void updatePackageCourseRequired(BigDecimal id,int required){
        PackageCourse packageCourse = new PackageCourse() ;
        packageCourse.setRequired(required);
        this.updateByWhereSql(packageCourse," id =" +id);
    }

    /**
     * 查询套餐下关联的课程数据列表(分层)
     * @param userId 用户ID
     * @param packageId 套餐ID
     * @param setCourseData 是否设置课程，true设置，false不设置
     * @return List<PackageCourse>
     */
    public Map<Integer,List<PackageCourse>> findUserLayeredPackageCourseByPackageId(BigDecimal userId,BigDecimal packageId,boolean setCourseData){
        //获取套餐课程原的有的课程目录
        Map<Integer,List<PackageCourse>> maps =  this.findLayeredPackageCourseByPackageId(packageId,setCourseData);
        //如果用户ID不存在 ，则直接返回
        if(!DataUtil.idIsNotNull(userId)){
            return maps;
        }
        CourseBuyRecord record = new CourseBuyRecord();
        record.setUserId(userId);
        record.setCourseId(packageId);
        //获取该套餐的正常购买记录
        List<CourseBuyRecord> courseBuyRecordList = courseBuyRecordBiz.findCourseBuyRecordByUserId(record,false);

        //已经激活的套餐
        if(ObjectUtils.isNotEmpty(courseBuyRecordList) && courseBuyRecordList.get(0).getStatus()==1){
            //购买记录，且已激活的套餐购买记录
            CourseBuyRecord courseBuyRecord = courseBuyRecordList.get(0);

            //套餐激活记录
            CourseBuyPackageCourse _courseBuyPackageCourse = new CourseBuyPackageCourse();
            _courseBuyPackageCourse.setOrderId(courseBuyRecord.getOrderId());
            _courseBuyPackageCourse.setOrderNo(courseBuyRecord.getOrderNo());
            _courseBuyPackageCourse.setUserId(userId);
            _courseBuyPackageCourse.setPackageId(packageId);
            List<CourseBuyPackageCourse> packageCourseList = courseBuyPackageCourseBiz.findCourseBuyPackageCourseList(_courseBuyPackageCourse,false);

            //以课程ID为KEY转成Map
            Map<BigDecimal,CourseBuyPackageCourse> packageCourseMpa = packageCourseList.stream().collect(Collectors.toMap(e->e.getCourseId(),e->e));
            if(ObjectUtils.isNotEmpty(maps)){
                maps.forEach((k,v)->{
                    if(k.intValue()==1 && ObjectUtils.isNotEmpty(v)){//类型，1课程，2阶段内容
                        List<PackageCourse> vList = new ArrayList<PackageCourse>();
                        v.forEach(e->{
                            CourseBuyPackageCourse courseBuyPackageCourse = packageCourseMpa.get(e.getCourseId());
                            //如果从激活记录中获取出来
                            if(ObjectUtils.isNotEmpty(courseBuyPackageCourse)){
                                vList.add(e);
                            }
                        });
                        //重新设置
                        maps.put(k,vList);
                    }
                    if(k.intValue()==2 && ObjectUtils.isNotEmpty(v)){//类型，1课程，2阶段内容
                        v.forEach(e->{
                            List<PackageCourse> childList = e.getChildList();
                            if(ObjectUtils.isNotEmpty(childList)){
                                List<PackageCourse> _childList = new ArrayList<PackageCourse>();
                                childList.forEach(child->{
                                    CourseBuyPackageCourse courseBuyPackageCourse = packageCourseMpa.get(child.getCourseId());
                                    //如果从激活记录中获取不出来，则删除
                                    if(ObjectUtils.isNotEmpty(courseBuyPackageCourse)){
                                        _childList.add(child);
                                    }
                                });
                                e.setChildList(_childList);
                            }
                        });
                    }
                });
            }
        }
        return maps;
    }

    /**
     * 查询套餐下关联的课程数据列表(分层)
     * @param packageId 套餐ID
     * @param setCourseData 是否设置课程，true设置，false不设置
     * @return List<PackageCourse>
     */
    public Map<Integer,List<PackageCourse>> findLayeredPackageCourseByPackageId(BigDecimal packageId,boolean setCourseData){
        List<PackageCourse> packageCourseList = this.findPackageCourseByPackageId(packageId,setCourseData);
        if(ObjectUtils.isNotEmpty(packageCourseList)){
            Map<BigDecimal,List<PackageCourse>> packageCourseListMaps = packageCourseList.stream().collect(Collectors.groupingBy(e->e.getParentId()));
            List<PackageCourse> parentList = packageCourseListMaps.get(new BigDecimal(0));
            if(ObjectUtils.isNotEmpty(parentList)){
                parentList.forEach(e->{
                    List<PackageCourse> childList = packageCourseListMaps.get(e.getId());
                    e.setChildList(childList);
                });
            }
            if(ObjectUtils.isNotEmpty(parentList)){
                Map<Integer,List<PackageCourse>> integerListMap = parentList.stream().collect(Collectors.groupingBy(e->e.getPackageType()));
                return integerListMap;
            }
        }
        return null;
    }
    /**
     * 查询套餐下关联的课程数据列表
     * @param packageId 套餐ID
     * @param setCourseData 是否设置课程，true设置，false不设置
     * @return List<PackageCourse>
     */
    public List<PackageCourse> findPackageCourseByPackageId(BigDecimal packageId,boolean setCourseData){
        PackageCourse packageCourse = new PackageCourse();
        packageCourse.setPackageId(packageId);
        return this.findList(packageCourse,setCourseData);
    }

    /**
     * 查询套餐下关联的课程数据列表
     * @param packageIds 套餐ID串
     * @param setCourseData 是否设置课程，true设置，false不设置
     * @return List<PackageCourse>
     */
    public List<PackageCourse> findPackageCourseByPackageIds(String packageIds,boolean setCourseData){
        PackageCourse packageCourse = new PackageCourse();
        packageCourse.setPackageIds(packageIds);
        return this.findList(packageCourse,setCourseData);
    }

    /**
     * 查询套餐所有包含的课程量
     * @param ids 套餐ID串
     * @return Map<BigDecimal,Integer>
     */
    public Map<BigDecimal,Integer> findPackageCourseNumMapByIds(String ids){
        if(StringUtils.isNotEmpty(ids)){
            List<PackageCourse> packageCourseList = this.find(" packageId in ("+ids+") and packageType=1",null,null);
            if(ObjectUtils.isNotEmpty(packageCourseList)){
                Map<BigDecimal,List<PackageCourse>> maps = packageCourseList.stream().collect(Collectors.groupingBy(e->e.getPackageId()));
                if(ObjectUtils.isNotEmpty(maps)){
                    String[] arr = ids.split(",");
                    Map<BigDecimal,Integer> resultMap = new HashMap<>();
                    Arrays.stream(arr).forEach(id->{
                        BigDecimal key = new BigDecimal(id);
                        List<PackageCourse> packageCourses = maps.get(key);
                        if(ObjectUtils.isNotEmpty(packageCourses)){
                            resultMap.put(key,packageCourses.size());
                        }else{
                            resultMap.put(key,0);
                        }
                    });
                    return resultMap;
                }
            }
        }
        return null;
    }

    //=========================================
    /**
     * 多条件查询套餐与课程关联的数据
     * @param packageCourse 查询条件
     * @param setCourseData 是否设置课程数据，true设置，false不设置
     * @return List<PackageCourse>
     */
    public List<PackageCourse> findList(PackageCourse packageCourse ,boolean setCourseData){
        StringBuilder whereSql = new StringBuilder(" 1=1 ");
        if(ObjectUtils.isNotEmpty(packageCourse)){
            if(DataUtil.idIsNotNull(packageCourse.getPackageId())){
                whereSql .append(" and packageId=").append(packageCourse.getPackageId());
            }
            String packageIds = StringUtils.subHeadTailString(packageCourse.getPackageIds(),",");
            if(StringUtils.isNotEmpty(packageIds)){
                whereSql .append(" and packageId in (").append(packageIds).append(")");
            }
            whereSql .append(" order by sort desc,id desc");
        }
        List<PackageCourse> packageCourseList = this.find(whereSql.toString(),null,null);
        //设置课程数据
        this.setCourseData(packageCourseList,setCourseData);
        return packageCourseList;
    }

    /**
     * 设置课程数据
     * @param packageCourseList
     * @param setCourseData
     * @return List<PackageCourse>
     */
    private List<PackageCourse> setCourseData(List<PackageCourse> packageCourseList,boolean setCourseData){
        if(ObjectUtils.isNotEmpty(packageCourseList) && setCourseData){
            String courseIds = packageCourseList.stream().filter(e->DataUtil.idIsNotNull(e.getCourseId())).map(e->e.getCourseId().toString()).distinct().collect(Collectors.joining(","));
            if(StringUtils.isNotEmpty(courseIds)){
                List<Course> courseList = courseBiz.findPackageCourseList(courseIds,false,false,false);
                if(ObjectUtils.isNotEmpty(courseList)){
                    Map<BigDecimal,Course> courseMaps = courseList.stream().collect(Collectors.toMap(e->e.getId(),e->e));
                    packageCourseList.forEach(e->{
                        if(e.getPackageType().intValue()==1){
                            BigDecimal courseId = e.getCourseId();
                            if(DataUtil.idIsNotNull(courseId)){
                                e.setCourse(courseMaps.get(courseId));
                            }
                        }
                    });
                }
            }
        }
        return packageCourseList;
    }

    private void setCourseService(List<PackageCourse>  packageCourses ,Course course,int type,BigDecimal packageId){
        Integer service =0;
        if(type==1||!packageCourses.isEmpty()){
            String courseIds = packageCourses.stream().filter(e -> ObjectUtils.isNotEmpty(e.getCourseId())).map(e -> e.getCourseId().toString()).collect(Collectors.joining(","));
            List<Integer> courseService = packageCourseDao.getCourseService(Course.class, courseIds);
            if(!courseService.isEmpty()){
                if(courseService.contains(3)){
                    service=3;
                }else if(courseService.contains(2)){
                    service=2;
                    if (course.getService()==1) {
                        service=3;
                    }
                }else if(courseService.contains(1)){
                    service=1;
                    if (course.getService()==2) {
                        service=3;
                    }
                }
            }
        }
        if (course.getService()==service) {
            return;
        }
        if(type==1&&service<course.getService()){
            return;
        }
        Course courseNew = new Course();
        courseNew.setId(packageId);
        courseNew.setService(service);
        courseBiz.updateById(courseNew,null);
    };
}
